package template;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import org.apache.http.util.TextUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Author: Allen Wang
 * Email:  181628396@qq.com
 * Time:   &time&
 */

public class AndroidMvpAction extends AnAction {
    Project project;
    VirtualFile selectGroup;
    int codeType = 0;
    int mvpOrMVVM = 0;
    String appid = "";

    @Override
    public void actionPerformed(AnActionEvent e) {
        project = e.getProject();
        System.out.println("test:" + appid);
        selectGroup = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
        mvpOrMVVM = Messages.showDialog(project, "代码模板类型", "MVP或者MVVM", new String[]{"MVP", "MVVM"}, 0, Messages.getQuestionIcon());
        getAppId();//偷偷获取appid
        if (mvpOrMVVM == 0) {
            //MVP代码模块
            codeType = Messages.showDialog(project, "代码类型", "Kotlin或者JAVA", new String[]{"Kotlin", "Java"}, 0, Messages.getQuestionIcon());
            String className = Messages.showInputDialog(project, "请输入类名称，Fragment或Activity结尾", "生成Mvp文件", Messages.getQuestionIcon());

            if (TextUtils.isEmpty(className)) {
                System.out.print("没有输入类名");
                return;
            }
            if (codeType == 0) {
                createKotlinCode(className);
            } else {
                createJavaCode(className);
            }
            createLayoutCode(className);
        } else {
            //MVVM代码模块
            codeType = Messages.showDialog(project, "界面代码类型", "Kotlin或者JAVA", new String[]{"Kotlin", "Java"}, 0, Messages.getQuestionIcon());
            String className2 = Messages.showInputDialog(project, "请输入类名称，Fragment或Activity结尾", "生成MVVM文件", Messages.getQuestionIcon());
            if (TextUtils.isEmpty(className2)) {
                System.out.print("没有输入类名");
                return;
            }
            if (codeType == 0) {
                createKotlinCodeForMVVM(className2);
            } else {
                createJavaCodeForMVVM(className2);
            }
            createLayoutCode(className2);
        }

        project.getBaseDir().refresh(false, true);
    }

    /**
     * 创建布局
     */
    private void createLayoutCode(String className) {
        boolean isFragment = className.toLowerCase().endsWith("fragment");
        if (className.endsWith("Fragment") || className.endsWith("fragment") || className.endsWith("Activity") || className.endsWith("activity")) {
            className = className.substring(0, className.length() - 8);
        }
        className = className.substring(0, 1).toUpperCase() + className.substring(1);
        //String path = selectGroup.getPath() + "/" + className.toLowerCase();
        //String packageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");

        /*Activity或者fragment*/
        String typeName = isFragment ? "Fragment" : "Activity";
        String layoutPath = project.getBasePath() + "/app/src/main/res/layout";
        String layoutContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
                "    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
                "    android:layout_width=\"match_parent\"\n" +
                "    android:layout_height=\"match_parent\"\n" +
                "    android:orientation=\"vertical\">\n" +
                "\n" +
                "</androidx.constraintlayout.widget.ConstraintLayout>";
        writetoFile(layoutContent, layoutPath, typeName.toLowerCase() + "_" + className.toLowerCase() + ".xml");
    }

    /**
     * 创建MVP架构
     */
    private void createKotlinCode(String className) {
        boolean isFragment = className.toLowerCase().endsWith("fragment");
        if (className.endsWith("Fragment") || className.endsWith("fragment") || className.endsWith("Activity") || className.endsWith("activity")) {
            className = className.substring(0, className.length() - 8);
        }
        className = className.substring(0, 1).toUpperCase() + className.substring(1);
        String path = selectGroup.getPath() + "/" + className.toLowerCase();
        String packageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");

        /*Contract*/
        String contract = readAndReplaceString("Contract", packageName, className);
        writetoFile(contract, path, className + "Contract.kt");
        /*Presenter*/
        String presenter = readAndReplaceString("Presenter", packageName, className);
        writetoFile(presenter, path, className + "Presenter.kt");

        /*Activity或者fragment*/
        String typeName = isFragment ? "Fragment" : "Activity";
        String placeString1 = "";
        String placeString2 = "";
        if (isFragment) {//fragment强制实现initView
            placeString1 = "import android.view.LayoutInflater;\n" +
                    "import android.view.View;";
            placeString2 = "\n" + "   override fun initView(inflater: LayoutInflater): View? {\n" +
                    "        return null\n" +
                    "    }";
        }else{
            registeActivityIntoManifest(packageName+"."+className+"Activity");
        }
        String compment = readAndReplaceString("Compment", packageName, className).replace("&type&", typeName).replace("&placeholder1&", placeString1).replace("&placeholder2&", placeString2);
        writetoFile(compment, path, className + typeName + ".kt");

    }

    /**
     * 创建MVP架构
     */
    private void createJavaCode(String className) {
        boolean isFragment = className.toLowerCase().endsWith("fragment");
        if (className.endsWith("Fragment") || className.endsWith("fragment") || className.endsWith("Activity") || className.endsWith("activity")) {
            className = className.substring(0, className.length() - 8);
        }
        className = className.substring(0, 1).toUpperCase() + className.substring(1);
        String path = selectGroup.getPath() + "/" + className.toLowerCase();
        String packageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");

        /*Contract*/
        String contract = readAndReplaceString("Contract", packageName, className);
        writetoFile(contract, path, className + "Contract.java");
        /*Presenter*/
        String presenter = readAndReplaceString("Presenter", packageName, className);
        writetoFile(presenter, path, className + "Presenter.java");

        /*Activity或者fragment*/
        String typeName = isFragment ? "Fragment" : "Activity";
        String placeString1 = "";
        String placeString2 = "";
        if (isFragment) {//fragment强制实现initView
            placeString1 = "import android.view.LayoutInflater;\n" +
                    "import android.view.View;";
            placeString2 = "\n" +
                    "    @Override\n" +
                    "    protected View initView(LayoutInflater inflater) {\n" +
                    "        return null;\n" +
                    "    }";

        }else{
            registeActivityIntoManifest(packageName+"."+className+"Activity");

        }
        String compment = readAndReplaceString("Compment", packageName, className).replace("&type&", typeName).replace("&placeholder1&", placeString1).replace("&placeholder2&", placeString2);
        writetoFile(compment, path, className + typeName + ".java");

    }


    /**
     * 创建MVVM架构
     */
    private void createKotlinCodeForMVVM(String className) {
        boolean isFragment = className.toLowerCase().endsWith("fragment");
        if (className.endsWith("Fragment") || className.endsWith("fragment") || className.endsWith("Activity") || className.endsWith("activity")) {
            className = className.substring(0, className.length() - 8);
        }
        className = className.substring(0, 1).toUpperCase() + className.substring(1);
        String path = selectGroup.getPath() + "/" + className.toLowerCase();
        String packageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");

        /*viewmodel*/
        String viewmodelContent = readAndReplaceString("ViewModel", packageName, className);
        writetoFile(viewmodelContent, path, className + "ViewModel.kt");

        /*Activity或者fragment*/
        String typeName = isFragment ? "Fragment" : "Activity";
        String placeString1 = "";
        String placeString2 = "";
        if (isFragment) {//fragment强制实现initView
            placeString1 = "import android.view.LayoutInflater;\n" +
                    "import android.view.View;";
            placeString2 = "\n" + "   override fun initView(inflater: LayoutInflater): View? {\n" +
                    "        return null\n" +
                    "    }";
        } else {
            placeString1 = "import android.os.Bundle;\n" +
                    "import " + appid + ".R;\n" +
                    "import com.bgn.baseframe.base.mvvm.BaseViewModelActivity";
            placeString2 = "override fun onCreate(savedInstanceState: Bundle?) {\n" +
                    "        super.onCreate(savedInstanceState)\n" +
                    "        setContentView(R.layout.activity_" + className.toLowerCase() + ")\n" +
                    "\n" +
                    "    }";
            registeActivityIntoManifest(packageName+"."+className+"Activity");
        }
        String compment = readAndReplaceString("CompmentMVVM", packageName, className).replace("&type&", typeName).replace("&placeholder1&", placeString1).replace("&placeholder2&", placeString2);
        writetoFile(compment, path, className + typeName + ".kt");

    }

    /**
     * 创建MVVM架构
     */
    private void createJavaCodeForMVVM(String className) {
        boolean isFragment = className.toLowerCase().endsWith("fragment");
        if (className.endsWith("Fragment") || className.endsWith("fragment") || className.endsWith("Activity") || className.endsWith("activity")) {
            className = className.substring(0, className.length() - 8);
        }
        className = className.substring(0, 1).toUpperCase() + className.substring(1);
        String path = selectGroup.getPath() + "/" + className.toLowerCase();
        String packageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");


        /*viewmodel*/
        String viewmodelContent = readAndReplaceString("ViewModel", packageName, className);
        writetoFile(viewmodelContent, path, className + "ViewModel.kt");

        /*Activity或者fragment*/
        String typeName = isFragment ? "Fragment" : "Activity";
        String placeString1 = "";
        String placeString2 = "";
        if (isFragment) {//fragment强制实现initView
            placeString1 = "import android.view.LayoutInflater;\n" +
                    "import android.view.View;";
            placeString2 = "\n" +
                    "    @Override\n" +
                    "    protected View initView(LayoutInflater inflater) {\n" +
                    "        return null;\n" +
                    "    }";

        } else {
            placeString1 = "import android.os.Bundle;\n" +
                    "import " + appid + ".R;\n" +
                    "import com.bgn.baseframe.base.mvvm.BaseViewModelActivity;";
            placeString2 = "    @Override\n" +
                    "    protected void onCreate(Bundle savedInstanceState) {\n" +
                    "        super.onCreate(savedInstanceState);\n" +
                    "        setContentView(R.layout.activity_" + className.toLowerCase() + ");\n" +
                    "    }";
            registeActivityIntoManifest(packageName+"."+className+"Activity");
        }
        String compment = readAndReplaceString("CompmentMVVM", packageName, className).replace("&type&", typeName).replace("&placeholder1&", placeString1).replace("&placeholder2&", placeString2);
        writetoFile(compment, path, className + typeName + ".java");

    }


    /*工具类方法*/
    private String readAndReplaceString(String fileName, String packageName, String className) {
        // String contract = readFile("Contract.txt").replace("&time&", time).replace("&package&", packageName).replace("&mvp&", mvpPath).replace("&Contract&", className + "Contract");
        String baseFilePath = "com.bgn.baseframe.base";

        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
        String path = (codeType == 0 ? "kotlin/" : "java/");
        return readFile(path + fileName + ".txt")
                .replace("&time&", time)
                .replace("&package&", packageName)
                .replace("&mvp&", baseFilePath)
                .replace("&className&", className);
    }


    private String readFile(String filename) {
        InputStream in = null;
        in = this.getClass().getResourceAsStream("code/" + filename);
        String content = "";
        try {
            content = new String(readStream(in));
        } catch (Exception e) {
        }
        return content;
    }

    private String readFileFromOtherPath(String path) {
        File floder = new File(path);
        InputStream is = null;
        String content;
        try {
            is = new FileInputStream(floder);
            int iAvail = is.available();
            byte[] bytes = new byte[iAvail];
            is.read(bytes);
            content = new String(bytes);
            is.close();
        } catch (Exception e) {
            return "";
        }
        return content;
    }

    private void writetoFile(String content, String filepath, String filename) {
        try {
            File floder = new File(filepath);
            // if file doesnt exists, then create it
            if (!floder.exists()) {
                floder.mkdirs();
            }
            File file = new File(filepath + "/" + filename);
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
                System.out.println(new String(buffer));
            }

        } catch (IOException e) {
        } finally {
            outSteam.close();
            inStream.close();
        }
        return outSteam.toByteArray();
    }


    /*获取项目applicationid的方法*/
    public void getAppId() {
        String gradleFilePath = project.getBasePath() + "/app/build.gradle";
        File file = new File(gradleFilePath);
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件

            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法，一次读一行
                result.append(System.lineSeparator() + s);
                if (!TextUtils.isEmpty(s) && s.contains("applicationId")) {
                    String lineString = s.trim().replaceAll("\\\"", "").trim();
                    ;
                    int start = lineString.indexOf("applicationId");
                    int end = lineString.length();
                    appid = lineString.substring(start + 14, end);
                    return;
                } else {
                    continue;
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return;
    }

    /*往manifest里面写入新建的Activity*/
    public void registeActivityIntoManifest(String manifestName) {
        String manifestFilePath = project.getBasePath() + "/app/src/main/AndroidManifest.xml";
        String fileString = readFileFromOtherPath(manifestFilePath);

        String replaceString = "\n" +
                "        <activity\n" +
                "            android:name=\"" + manifestName + "\"\n" +
                "            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n" +
                "            android:screenOrientation=\"portrait\"></activity>\n" +
                "\n" +
                "    </application>";
        fileString = fileString.replace("</application>", replaceString);
        writetoFile(fileString, project.getBasePath() + "/app/src/main", "AndroidManifest.xml");
    }

}
